package com.qingyun.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qingyun.common.core.mybatisplus.core.ServicePlusImpl;
import com.qingyun.common.core.page.PagePlus;
import com.qingyun.common.core.page.TableDataInfo;
import com.qingyun.common.exception.ServiceException;
import com.qingyun.common.utils.PageUtils;
import com.qingyun.security.utils.SecurityUtils;
import com.qingyun.shop.domain.TiktokBankCard;
import com.qingyun.shop.domain.TiktokProxy;
import com.qingyun.shop.domain.TiktokWithdrawApply;
import com.qingyun.shop.domain.bo.TiktokWithdrawApplyAddBo;
import com.qingyun.shop.domain.bo.TiktokWithdrawApplyBo;
import com.qingyun.shop.domain.bo.TiktokWithdrawApplyQueryBo;
import com.qingyun.shop.domain.vo.TiktokBankCardVo;
import com.qingyun.shop.domain.vo.TiktokWithdrawApplyVo;
import com.qingyun.shop.mapper.TiktokBankCardMapper;
import com.qingyun.shop.mapper.TiktokProxyMapper;
import com.qingyun.shop.mapper.TiktokWithdrawApplyMapper;
import com.qingyun.shop.service.ITiktokWithdrawApplyService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 商户提现申请Service业务层处理
 *
 * @author qingyun
 * @date 2021-10-19
 */
@Service
@AllArgsConstructor
@Slf4j
public class TiktokWithdrawApplyServiceImpl extends ServicePlusImpl<TiktokWithdrawApplyMapper, TiktokWithdrawApply, TiktokWithdrawApplyVo> implements ITiktokWithdrawApplyService {

    private final TiktokProxyMapper proxyMapper;

    private final TiktokBankCardMapper bankCardMapper;

    private final MapperFacade mapperFacade;

    @Override
    public TiktokWithdrawApplyVo queryById(Long id){

        TiktokWithdrawApplyVo withdrawApplyVo = getVoById(id);

        TiktokBankCard bankCard = bankCardMapper.selectById(withdrawApplyVo.getBankId());

        withdrawApplyVo.setBankCard(BeanUtil.toBean(bankCard, TiktokBankCardVo.class));

        return withdrawApplyVo;
    }

    @Override
    public TableDataInfo<TiktokWithdrawApplyVo> queryPageList(TiktokWithdrawApplyQueryBo bo) {
        if (!SecurityUtils.isManager() && bo.getProxyId() == null) {
            bo.setProxyId(SecurityUtils.getProxy().getId());
        }
        PagePlus<TiktokWithdrawApply, TiktokWithdrawApplyVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo));
		for (TiktokWithdrawApplyVo tiktokWithdrawApplyVo : result.getRecordsVo()) {
			TiktokBankCard tiktokBankCard = bankCardMapper.selectById(tiktokWithdrawApplyVo.getBankId());
			if(SecurityUtils.isProxy()) {
				tiktokBankCard.setBankNumber(DesensitizedUtil.bankCard(tiktokBankCard.getBankNumber()));
			}
			tiktokWithdrawApplyVo.setBankCard(mapperFacade.map(tiktokBankCard,TiktokBankCardVo.class));
		}
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<TiktokWithdrawApplyVo> queryList(TiktokWithdrawApplyQueryBo bo) {
        return listVo(buildQueryWrapper(bo));
    }

    private LambdaQueryWrapper<TiktokWithdrawApply> buildQueryWrapper(TiktokWithdrawApplyQueryBo bo) {
        LambdaQueryWrapper<TiktokWithdrawApply> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getProxyId() != null, TiktokWithdrawApply::getProxyId, bo.getProxyId());
        lqw.eq(bo.getStatus() != null, TiktokWithdrawApply::getStatus, bo.getStatus());
        lqw.like(StringUtils.isNotBlank(bo.getUserName()), TiktokWithdrawApply::getUserName, bo.getUserName());
        lqw.orderByDesc(TiktokWithdrawApply::getCreateTime);
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(TiktokWithdrawApplyAddBo bo) {
        Long proxyId = SecurityUtils.getProxy().getId();
        TiktokProxy proxy = proxyMapper.selectById(proxyId);

        TiktokBankCard tiktokBankCard = bankCardMapper.selectById(bo.getBankId());
        if (tiktokBankCard == null) {
            throw new ServiceException("您的银行卡信息不存在");
        }

		Integer count = bankCardMapper.selectCount(Wrappers.query(new TiktokBankCard().setProxyId(proxy.getId()).setStatus(0)));
		if (count < 1) {
			throw new ServiceException("您现在暂无可用的银行卡，请先去创建");
		}

        if (bo.getWithdrawAmount().compareTo(proxy.getUsableBalance()) > 0) {
            throw new ServiceException("您提现的金额不能大于可用余额");
        }

        TiktokWithdrawApply withdrawApply = BeanUtil.toBean(bo, TiktokWithdrawApply.class);

        withdrawApply.setProxyId(proxyId);
        withdrawApply.setUserId(SecurityUtils.getUser().getUserId());
        withdrawApply.setUserName(SecurityUtils.getUser().getUserName());

        if (save(withdrawApply)) {
            // 将提现的金额冻结
            // 冻结金额 + 待提现金额
            proxy.setFreezeBalance(NumberUtil.add(proxy.getFreezeBalance(),bo.getWithdrawAmount()));
            // 可提现金额 - 待提现金额
            proxy.setUsableBalance(NumberUtil.sub(proxy.getUsableBalance(),bo.getWithdrawAmount()));
            proxyMapper.updateById(proxy);
        } else {
            log.debug("提现申请插入失败");
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(TiktokWithdrawApplyBo bo) {
        TiktokWithdrawApply update = BeanUtil.toBean(bo, TiktokWithdrawApply.class);

        return updateById(update);
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        return removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean check(Long id, Integer status, String rejectReason) {

        TiktokWithdrawApply withdrawApply = baseMapper.selectById(id);
        TiktokProxy proxy = proxyMapper.selectById(withdrawApply.getProxyId());

        withdrawApply.setStatus(status);
        if (status == 1) {
            // 提现成功

            withdrawApply.setFinishTime(new Date());

            // 冻结金额 - 待提现金额
            proxy.setFreezeBalance(proxy.getFreezeBalance().subtract(withdrawApply.getWithdrawAmount()));
            proxy.setTotalBalance(NumberUtil.sub(proxy.getTotalBalance(),withdrawApply.getWithdrawAmount()));

            proxyMapper.updateById(proxy);

        } else if (status == 2) {
            // 提现驳回

            withdrawApply.setRejectReason(rejectReason);

            // 将冻结的金额返还到可提现的金额里
            proxy.setFreezeBalance(proxy.getFreezeBalance().subtract(withdrawApply.getWithdrawAmount()));
            // 可提现金额加回待提现的金额
            proxy.setUsableBalance(proxy.getUsableBalance().add(withdrawApply.getWithdrawAmount()));
//            // 总金额加回待提现的金额
//            proxy.setTotalBalance(proxy.getTotalBalance().add(withdrawApply.getWithdrawAmount()));

            proxyMapper.updateById(proxy);
        } else {
            throw new ServiceException("未知错误，请联系平台负责人");
        }

        return baseMapper.updateById(withdrawApply) > 0;
    }
}
